# python要从注释开始 根据python格式要求应该在#后加一个空格
# 这是单行注释
# 当python的解释器阅读Python代码是看到#会越过本行
print("study")

# 单步执行
print("单步执行程序")  # 在代码最后一行添加注释与代码间保留两个空格

""" 
多行注释
行数很多的时候使用
"""    
print("多行注释测试")

"""
单行#号加空格
代码后注释应该空两格
代码规范pep8
文档地址：https://www.python.org/dev/peps/pep-0008/
谷歌有对应的中文文档：http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/
任何语言的程序员，编写出符合规范的代码，是开始程序生涯的第一步
"""

# 算数运算符

print(1+1)  # +
print(1-1)  # -
print(1*1)  # *
print(3/2)  # /
print(3//2)  # //取整除
print(3%2)  # %
print(1.01**365)  # ** 幂

# 程序执行原理

"""
cpu 复制程序执行
硬盘 保存程序
python 有解释器解释为二进制由cpu从硬盘拷贝到内存然后由cpu与内存交互执行
变量 复则保存数据 如何保存？ 由cpu把变量复制到内存
"""

# 变量的使用及类型

# 定义一个变量
# 变量的类型
# 变量的命名规范

# 变量名 = 值
study = 100
print(study)

# 计算变量 
apple = 5
sum = 10
rmb = apple * sum
mj = 10  # 买苹果减10元
# 变量只有第一次出现的时候才定义变量
rmb = rmb - mj
print(rmb)

# 变量的类型 根据个人信息 定义时不需要指定
# 在运行时解释器会根据右边数据推导出类型
name = "小明"  # 字符串加""
print(name)
sex =  "男"
print(sex)
hight = 175
print(hight)

"""
python 中包括数字型和非数字型两种
数字型 整型(int) 浮点型(float) 布尔型(bool)0(假)!0(真) 复数型(complex)(主要用于科学计算有两部分实步,虚步)
非数字型 字符串 列表 元祖 字典
"""
# 根据type函数查看类型
print(type(name))
print(type(hight))
fl = 1000.0
bo = True
print(type(fl))
print(type(bo))
"""
python 2.0中不同长度的整数对应的类型
分int与long
ptyhon 3.0只有int
"""
print(type(2**32))
print(type(2**64))

# 不同类型间的计算
i = 10
f = 10.5
b = True  # true = 1 flast = 0
print(i+f+b)

# 字符串计算和拼接
print(name + "--" + sex)  # 字符串相加可以拼接字符串
print(name * 10)  # 字符串只能与字符串相加和字符串与数字相乘

# 输入变量
username = input("请输入你的名字：")  # input("提示信息")
print(username)

# 类型转换函数
s = "zhao"
print(int(f))
print(float(i))
print(bool(i))
si = str(i)
print(int(si))
print(float(si))

# 练习数如与转变
apple = input("输入价格：")
sum = input("输入重量：")
rmb = float(apple) * float(sum)
print(int(rmb))

# 格式化输入输出
# %s字符串 %d整数 %f小数 %%输出% 语法print("%d" % 变量)
print("%s" % apple)
print("%d" % rmb)
print("%f" % f)
print("%f%%" % f)

# 07结束10-31

# 变量的命名规范
# 与C语言相同 字母数字下划线组成 不能用数字开头 不能用关键字
# 关键字 import keyword 引入 0.500000%
# ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
import keyword

print(keyword.kwlist)

# 标识符区分大小写（重点）
# 在赋值语句左右保留一空格
# 都使用小写字母
# 单词之间_链接
# 例：user_name pass_word ...
# 变量有多个单词用驼峰命名 小驼峰 大驼峰（不推荐命名变量）

# 判断语句
# python中空格tab不共用
age = int(input("请出示身份证："))
if age <= 18 :
    print(name+"未成年不能进")
elif name == "小明" :
    print(name+"被拉黑不能进入")        
else :
    print(name+"上多久")
# 比较运算符
# == ！= > < >= <=
# if语句下放的缩进是一个完整的代码块
# elif == else if
# 逻辑运算符 and or not 与 或 非
if age >= 18 and name != "小明" :
    print("不能进")
else :
    print("欢迎")  
if age <= 18 or name != "小明":
    print("不能进")
else:
    print("欢迎")
is_empty = False    
if not is_empty :
    print("cuo")
else :
    print(0)

# 案例石头剪刀布   
# 设置石头（1） 剪刀（2） 布（3）
# 用import导入  随机
import random  # 引入随机数

geme_input = int(input("请出拳"))
geme = random.randint(1,3)

print("玩家出的是 %d - 电脑出的是 %d" % (geme_input,geme))

if ((geme == 1 and geme_input == 3) 
        or (geme == 2 and geme_input == 1) 
        or (geme == 3 and geme_input == 2)) :

    print("玩家胜")
elif geme == geme_input :
    
    print("平局")    
else :
    
    print("电脑胜")    

# 程序三大流程 顺序 分支 循环
# 循环
# while循环
i = 1 # 初始条件
while i < 5:
    print("循环")
    i = 1+i
# 例：从0加到100
num = 0
re = 0
while num <= 100:
    re += num
    num += 1
print("和为%d" % re)
# 例：计算0到100间所有偶数和
# 写循环准备所有偶数
num_1 = 0
re_1 = 0
while num_1 <= 100:
    if num_1 % 2 == 0:
        re_1 += num_1
    num_1 += 1    
print("所有偶数和为%d" % re_1)
# black 关键字跳出循环
# continue 当条件满足不执行其他
num_2 = 0
while num_2 < 10:
    if num_2 == 3:
        num_2 += 1    
        continue  #如果要使用continue需要确认计数是否更改
    print(num_2)
    num_2 += 1    
# 例 ：打印小星星
num_3 = 0
while num_3 <= 5:
    print("*" * num_3)
    num_3 += 1
# print 扩展end="" 打印结束替换
# 使用循环嵌套实现
num_row = 1
while num_row <=5:
    num_col = 1
    while num_col <= num_row :
        print("*",end="")
        num_col += 1
    print("")    
    num_row += 1
# 例： 输出九九乘法表
# 转义字符扩展 \t 制表符输出 \n 换行符输出
num_row_1 = 0
while num_row_1 <10:
    num_col_1 = 1
    while num_col_1 <= num_row_1:
        he = num_col_1 * num_row_1
        print("%d * %d = %d" % (num_col_1, num_row_1, he), end="\t")
        num_col_1 += 1
    print("")
    num_row_1 += 1

# 函数
# 函数把独立的代码块组成一个模块
# 函数的定义语法
# 函数不调用不显示
del_name = "溜溜"


def jiujiu_cfb() :  #例：定义九九乘法表函数 函数命名与变量同规则
    """九九乘法表"""
    num_row_1 = 0
    while num_row_1 < 10:
        num_col_1 = 1
        while num_col_1 <= num_row_1:
            he = num_col_1 * num_row_1
            print("%d * %d = %d" % (num_col_1, num_row_1, he), end="\t")
            num_col_1 += 1
        print("")
        num_row_1 += 1
print(del_name)        
# 调用九九乘法表函数
jiujiu_cfb()
# 函数的注释 在函数定义上方保留两个空行 或在函数命下加入多行注释
print(del_name)

# 函数的参数


def sum_he(num_1,num_2) :  # 形参
    """求和"""
    re = num_1 + num_2
    return re

print(sum_he(10,1))  # 实参

# 函数的嵌套调用


def sum_he_je(num_1,num_2) :
    """和加积"""
    re = num_1 + num_2 * sum_he(num_1,num_2)
    return re

print(sum_he_je(11,10))


def print_line(char = "-",num = 50) :
    print(char * num)

print_line("&",50)
print_line("#")
print_line()

# 模块 python的核心 所有.py都是一个模块 模块名也算一个标识符与变量相同命名规则
# 引用第一个模块
import oneClass

print(oneClass.one_name)

# 模块编译后会建立缓存pyc文件

# 列表（高级变量类型）
# 列表 == 数组 对应的关键字List 是python中最频繁的数据类型
name_list = ['张三','李四','王五']
for x in name_list :
    print(x)
# 列表索引
# 索引从0开始
print(name_list[0])

# python 对列表的操作
"""
| 1 | 增加列表.insert(索引, 数据) |	在指定位置插入数据

    | | | 列表.append(数据) | 在末尾追加数据

    | | | 列表.extend(列表2) | 将列表2 的数据追加到列表 |

| 2 | 修改 | 列表[索引] = 数据 | 修改指定索引的数据 |

| 3 | 删除 | del 列表[索引] | 删除指定索引的数据 |

    | | | 列表.remove[数据] | 删除第一个出现的指定数据 |

    | | | 列表.pop | 删除末尾数据 |

    | | | 列表.pop(索引) | 删除指定索引数据 |

    | | | 列表.clear | 清空列表 |

| 4 | 统计 | len(列表) | 列表长度 |

    | | | 列表.count(数据) | 数据在列表中出现的次数 |

| 5 | 排序 | 列表.sort() | 升序排序 |

    | | | 列表.sort(reverse=True) | 降序排序 
    | | | 列表.reverse() | 逆序、反转 |
"""
# 列表练习
age_list = ["10","20","30","40"]  # 定义列表
name_list.insert(4,"赵六")  # 添加
age_list.extend(name_list)  # 两个列表组合
name_list_name = name_list.index("李四")  # 获取索引
age_list[0] = '15'  # 修改数据
age_list.sort()  # 升序
age_list.sort(reverse = True)   # 降序

print(name_list_name)
print(age_list)

# 关键字 函数 方法
# 关键字是表示特殊含义的关键词，不用带括号
# 函数实现啦独立性 可以直接调用
# 方法需要 通过对象来输入

# 循环遍历
# for 参数 in 变量 迭代遍历

# 元祖
# 与列表类似 与列表不同:1()组成2不能修改 可以保存不同类型的数据
# 定义一个元祖
tuple_name = ("脑虎",10,"男",1.3)
print(tuple_name)
# 元祖的常用操作
# index count
print(tuple_name.count(10))
print(tuple_name.index(10))
for x in tuple_name :
    print(x)  # 使用字符串拼接不方便

# 元祖应用场景 函数的返回值 参数 格式字符串 让列表不能更改 
# 格式化字符串 可以用元祖拼接
print("%s 年龄是 %d 性别是 %s 体重是 %.2f" % tuple_name)
# 元祖与列表转换
print(type(list(tuple_name)))
print(type(tuple(age_list)))

# 字典 除啦列表最灵活的数据类型 列表是有序集合 字典是无序集合 (josn)
zd_name = {"name":"脑虎",
           "usernaem" : "naohu",
           "password" : 123,
            }
print(zd_name)
# 字典取值 在取值是key不存在会报错
print(zd_name['name'])
# 字典修改
zd_name["name"] = "大脑虎"
# 字典增加
zd_name["age"] = 18
# 字典删除
zd_name.pop("password")
print(zd_name)
# 字典合并统计清空
print(len(zd_name))
# 合并 字典.update(字典)相同覆盖
# 清空 字典.clear()
# 遍历
for_dint = {}
i = 0
for k in zd_name :
    for_dint[i] = k
    i += 1
print(for_dint)
# 字典列表的引用场景
# 列表嵌套字典

# 字符串
str_1 = "aaa bbb"
print(str_1[4])  # 取出小字符
for x in str_1:
    print(x)

# count index len
print(len(str_1))
print(str_1.count("a"))
print(str_1.index("a"))  # 若有相同取第一个

# 字符串常用方法
# 1) 判断类型 - 9

#     方法                	说明
#     string.isspace()  	如果 string 中只包含空格，则返回 True
#     string.isalnum()  	如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True
#     string.isalpha()  	如果 string 至少有一个字符并且所有字符都是字母则返回 True
#     string.isdecimal()	如果 string 只包含数字则返回 True，全角数字
#     string.isdigit()  	如果 string 只包含数字则返回 True，全角数字、⑴、\u00b2
#     string.isnumeric()	如果 string 只包含数字则返回 True，全角数字，汉字数字
#     string.istitle()  	如果 string 是标题化的(每个单词的首字母大写)则返回 True
#     string.islower()  	如果 string 中包含至少一个区分大小写的字符，并且所有这些(区分大小写的)字符都是小写，则返回 True
#     string.isupper()  	如果 string 中包含至少一个区分大小写的字符，并且所有这些(区分大小写的)字符都是大写，则返回 True

#     2) 查找和替换 - 7

#     方法                                      	说明
#     string.startswith(str)                  	检查字符串是否是以 str 开头，是则返回 True
#     string.endswith(str)                    	检查字符串是否是以 str 结束，是则返回 True
#     string.find(str, start=0, end=len(string))	检测 str 是否包含在 string 中，如果 start 和 end 指定范围，则检查是否包含在指定范围内，如果是返回开始的索引值，否则返回 - 1
#     string.rfind(str, start=0, end=len(string))	类似于 find()，不过是从右边开始查找
#     string.index(str, start=0, end=len(string))	跟 find() 方法类似，不过如果 str 不在 string 会报错
#     string.rindex(str, start=0, end=len(string))	类似于 index()，不过是从右边开始
#     string.replace(old_str, new_str, num=string.count(old))	把 string 中的 old_str 替换成 new_str，如果 num 指定，则替换不超过 num 次

#     3) 大小写转换 - 5

#     方法                 	说明
#     string.capitalize()	把字符串的第一个字符大写
#     string.title()     	把字符串的每个单词首字母大写
#     string.lower()     	转换 string 中所有大写字符为小写
#     string.upper()     	转换 string 中的小写字母为大写
#     string.swapcase()  	翻转 string 中的大小写

#     4) 文本对齐 - 3

#     方法                  	说明
#     string.ljust(width) 	返回一个原字符串左对齐，并使用空格填充至长度 width 的新字符串
#     string.rjust(width) 	返回一个原字符串右对齐，并使用空格填充至长度 width 的新字符串
#     string.center(width)	返回一个原字符串居中，并使用空格填充至长度 width 的新字符串

#     5) 去除空白字符 - 3

#     方法             	说明
#     string.lstrip()	截掉 string 左边（开始）的空白字符
#     string.rstrip()	截掉 string 右边（末尾）的空白字符
#     string.strip() 	截掉 string 左右两边的空白字符

#     6) 拆分和连接 - 5

#     方法                       	说明
#     string.partition(str)    	把字符串 string 分成一个 3 元素的元组(str前面, str, str后面)
#     string.rpartition(str)   	类似于 partition() 方法，不过是从右边开始查找
#     string.split(str="", num)	以 str 为分隔符拆分 string，如果 num 有指定值，则仅分隔 num + 1 个子字符串，str 默认包含 '\r', '\t', '\n' 和空格
#     string.splitlines()      	按照行('\r', '\n', '\r\n')分隔，返回一个包含各行作为元素的列表
#     string.join(seq)         	以 string 作为分隔符，将 seq 中所有的元素（的字符串表示）合并为一个新的字符串

# 字符串的基本方法
str_2 = "      "  # 判断字符串是否全为空格
print(str_2.isspace())

str_3 = "11111"  # 判断是否为数字 不能判断小数
print(str_3.isdecimal())  # 全部为阿啦伯数字
print(str_3.isdigit())  # 特殊的数字 如unicode字符串
print(str_3.isnumeric())  # 可判断中文数字(最强)

# 字符串的查找和替换
str_4 = "suss aaaa"
print(str_4.startswith("s"))  # 查找第一位
print(str_4.endswith("a"))  # 查看最后一位
print(str_4.find("u"))  # 查找
print(str_4.replace("u","a"))  # 替换 会生成新的字符串原有字符串的内容不变

# 文本对齐 & 去除空白字符
parm = [
        "aaa\t\n",
        "bbb",
        "\t\nccc",
        "ddd"
    ]
for x in parm:
    print(x.strip())
    print(x.center(10))
    print(x.ljust(10))
    print(x.rjust(10))

# 拆分和连接
str_5 = "aaaabbb bbbbbbbaaaaa cccccccddddd"
print(str_5.split())  # 默认用空格
list_1 = str_5.split()
print(" ".join(str_5))

# 切片
str_6 = "0123456789"
print(str_6[2:5])
print(str_6[2:])
print(str_6[:5])
print(str_6[:])
print(str_6[::2])
print(str_6[1::2])  # 取出从1开始跳2位
print(str_6[-1])  # 取出9
print(str_6[2:-1])  # 取出1到8
print(str_6[-2])  # 取出89
print(str_6[-1::-1])  # 逆序

# 公共方法
# 内置函数针对高级数据类型 len个数 max最大值 min最小值 del删除 cmp比较只支持比较运算符字典不能比较大小
# 切片[::] 高级数据类型切片
# 运算符 + - * /  高级数据(除字典) * + extends append in not in 
# +产生新列表 extend修改原列表

# for else
# for k in str_6 : 
#  循环体
# else : 
#   未通过break退出执行
for num in ['1','2','3'] :
    print(num)
else :
    print('end')

# for else 常见使用场景
str_7 = [
    {"name":"脑虎"},
    {"name":"溜溜"},
    {"name":"大蛙"},
    {"name":"傻狗"}
]

find_name = "大蛙"

for f_name in str_7:
    
    if f_name['name'] == find_name:
        print("找到了 %s" %find_name)
        break
else:
    print("查无此人")